import base64
import os
import sqlite3

from PySide2.QtWidgets import QHBoxLayout, QWidget, QVBoxLayout
from qfluentwidgets import MessageBoxBase, LineEdit, SubtitleLabel, PushButton
from PySide2.QtCore import QAbstractListModel, QModelIndex, Qt, QRect, QSize, Signal
from PySide2.QtGui import QPixmap, QPalette, QBrush, QColor, QFont, QImage
from PySide2.QtWidgets import QStyledItemDelegate, QStyle, QListView

from DataBase import DatabaseManager, DatabaseWorker


class SearchFriendMessageBox(MessageBoxBase):
    """
    搜索好友消息框
    """

    def __init__(self, parent=None):
        super().__init__(parent)
        self.queue_1 = None
        self.list_view = None
        self.index = None
        self.search_results = None
        self.titleLabel = SubtitleLabel('搜索好友')

        self.remarknameLineEdit = LineEdit()
        self.remarknameLineEdit.setPlaceholderText('请输入好友的备注')
        self.remarknameLineEdit.setClearButtonEnabled(True)

        self.search_button = PushButton('搜索')
        self.search_button.clicked.connect(self.search_friend)

        # self.yesButton.setText("搜索")
        self.cancelButton.setText("取消")
        self.hideYesButton()
        self.buttonLayout.insertStretch(0, 1)

        # 添加输入框与搜索按钮的容器
        layout_search = QHBoxLayout()
        layout_search.addWidget(self.remarknameLineEdit)
        layout_search.addWidget(self.search_button)
        container_search = QWidget()
        container_search.setLayout(layout_search)

        # 添加显示搜索到的好友列表的容器
        self.result_frame = QWidget()

        # 将组件添加到布局中
        self.viewLayout.addWidget(self.titleLabel)
        self.viewLayout.addWidget(container_search)

        # 设置对话框的最小宽度
        self.widget.setMinimumWidth(350)

    def set_index(self, index, queue_1):
        self.index = index
        self.queue_1 = queue_1

    def search_friend(self):
        # 定义搜索关键字
        keyword = self.remarknameLineEdit.text()

        # 使用上下文管理器连接到SQLite数据库
        db_path = './bots/bot{}/information.db'.format(self.index)
        try:
            with sqlite3.connect(db_path) as conn:
                cursor = conn.cursor()

                # 构建参数化的SQL查询
                query = """
                    SELECT remarkname, nickname, avatar, username 
                    FROM users 
                    WHERE remarkname LIKE ? OR nickname LIKE ?;
                    """

                # 执行查询
                cursor.execute(query, ('%' + keyword + '%', '%' + keyword + '%'))
                results = cursor.fetchall()
                self.search_results = results

                # 提交事务（在使用上下文管理器时，commit 是自动处理的）
                # conn.commit()  # 不需要显式调用 commit，因为上下文管理器会自动提交

        except sqlite3.Error as e:
            self.logger.error(f"数据库错误: {e}")
            self.search_results = []
        except Exception as e:
            self.logger.error(f"未知错误: {e}")
            self.search_results = []

        # 如果有搜索结果，则显示
        if self.search_results:
            self.show_search_results()

    def show_search_results(self):
        if not self.list_view:
            # 创建新的列表视图
            self.list_view = FriendListView(self.index, self.search_results)
            self.list_view.clicked.connect(self.send_to_friend)

            # 创建新的布局
            layout_result = QVBoxLayout()
            layout_result.addWidget(self.list_view)
            layout_result.setContentsMargins(0, 0, 0, 0)

            # 设置 frame 的布局为新创建的布局
            self.result_frame.setLayout(layout_result)

            # 将新的搜索结果容器添加到布局中
            self.viewLayout.addWidget(self.result_frame)
        else:
            self.list_view.model.update_friends_data(self.search_results)  # 更新搜索到的好友数据

    def clear_layout(self, parent):
        """辅助函数：清除给定父窗口的所有子控件和布局"""
        if parent.layout():
            while parent.layout().count():
                child = parent.layout().takeAt(0)
                if child.widget() is not None:
                    child.widget().deleteLater()
                elif child.layout() is not None:
                    self.clear_layout(child.widget())  # 递归清除嵌套的布局
            parent.setLayout(None)

    def send_to_friend(self, index, userinfo):
        # 向主界面发送userinfo，展示该好友的聊天窗口
        self.queue_1.put((self.index, "SearchFriend", userinfo))

        # 清空搜索结果
        self.search_results = None
        # 清空搜索框
        self.remarknameLineEdit.clear()
        # 重置搜索结果列表
        if self.list_view:
            self.list_view.model.update_friends_data([])

        # # 关闭搜索好友窗口
        # self.close()


class FriendListModel(QAbstractListModel):
    def __init__(self, friends_data=None, parent=None):
        super().__init__(parent)
        # print(friends_data)
        self.friends_data = [friend for friend in (friends_data or [])]
        avatar_data = ''
        avatar_data = base64.b64decode(avatar_data.split(',')[1])
        self.DEFAULT_AVATAR_PATH = QImage.fromData(avatar_data)

    def rowCount(self, parent=QModelIndex()):
        return len(self.friends_data)

    def data(self, index: QModelIndex, role: int = Qt.DisplayRole):
        if not index.isValid():
            return None
        friend = self.friends_data[index.row()]
        # print("======================================================")
        # print(friend)
        if role == Qt.DisplayRole:
            if friend[0]:
                return friend[0]  # 备注存在返回备注
            else:
                return friend[1]  # 昵称存在返回昵称
        elif role == Qt.DecorationRole:
            local_avatar_path = friend[2]
            if local_avatar_path and os.path.exists(local_avatar_path) and os.path.getsize(local_avatar_path) > 0:
                pixmap = QPixmap(local_avatar_path)
            else:
                pixmap = QPixmap(self.DEFAULT_AVATAR_PATH)
            return pixmap.scaledToHeight(50)
        elif role == Qt.UserRole + 1:
            return "昵称：" + friend[1]  # 返回昵称
        return None

    def update_friends_data(self, new_friends_data):
        """更新数据源并通知视图数据发生变化"""
        filtered_data = [friend for friend in (new_friends_data or [])]
        if self.friends_data != filtered_data:
            self.beginResetModel()
            self.friends_data = filtered_data
            self.endResetModel()

    def get_friends_data(self):
        return self.friends_data

    def is_valid_friend(self, friend):
        """检查 friend[2] 路径下是否存在文件"""
        if len(friend) > 2 and friend[2]:
            return os.path.exists(friend[2])
        return False


class FriendItemDelegate(QStyledItemDelegate):
    def paint(self, painter, option, index):
        painter.save()

        color_group = QPalette.Active if option.state & QStyle.State_Active else QPalette.Inactive
        color_role = QPalette.Highlight if option.state & QStyle.State_Selected else QPalette.Window
        brush = QBrush(option.palette.color(color_group, color_role))
        painter.fillRect(option.rect, brush)

        # 根据选中状态改变背景色
        if option.state & QStyle.State_Selected:
            painter.fillRect(option.rect, QColor(201, 199, 198))  # 选中状态的背景色

        # 根据鼠标悬停状态改变文本颜色
        if option.state & QStyle.State_MouseOver:
            painter.setPen(QColor(0, 0, 255))  # 鼠标悬停时的文本颜色

        # 设置字体和颜色
        font = QFont()
        remarkname_color = QColor('black')
        nickname_color = QColor('gray')

        # 绘制头像
        avatar = index.data(Qt.DecorationRole)
        avatar_rect = QRect(option.rect.x() + 10, option.rect.y() + 10, 40, 40)
        painter.drawPixmap(avatar_rect, avatar)

        # 绘制备注或昵称
        nickname = index.data(Qt.DisplayRole)
        nickname_rect = QRect(option.rect.x() + 60, option.rect.y() + 10, option.rect.width() - 80, 20)
        font.setPointSize(11)  # 设置字体大小
        painter.setFont(font)
        painter.setPen(remarkname_color)
        painter.drawText(nickname_rect, Qt.AlignVCenter, nickname)

        # 绘制昵称
        message = index.data(Qt.UserRole + 1)
        message_rect = QRect(option.rect.x() + 60, option.rect.y() + 30, option.rect.width() - 80, 20)
        font.setPointSize(9)  # 设置字体大小
        painter.setFont(font)
        painter.setPen(nickname_color)
        painter.drawText(message_rect, Qt.AlignVCenter, message)

        painter.restore()

    def sizeHint(self, option, index):
        # return QSize(200, 65)  # 返回每个列表项的推荐尺寸
        return QSize(230, 60)


class FriendListView(QListView):
    clicked = Signal(int, tuple)  # 信号，参数为好友的索引

    def __init__(self, index, friends_data=None, parent=None):
        super().__init__(parent)
        self.index = index
        self.model = FriendListModel(friends_data)
        self.delegate = FriendItemDelegate(self)
        self.setItemDelegate(self.delegate)
        self.setModel(self.model)
        self.setFrameShape(QListView.NoFrame)
        self.viewport().setContentsMargins(0, 0, 0, 0)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        # 定义滚动条的样式
        scrollbar_style = """
            QScrollBar:vertical {
                border: none;
                background: transparent;
                width: 5px;
                opacity: 0.0;
                border-radius: 20px;
            }
            QScrollBar:hover:vertical {
                opacity: 1.0;
            }
            QScrollBar::handle:vertical {
                background: #aeabaa;
                min-height: 20px;
            }
            QScrollBar::add-line:vertical {
                height: 0px;
            }
            QScrollBar::sub-line:vertical {
                height: 0px;
            }
            QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical {
                border: none;
                width: 1px;
                height: 1px;
                background: none;
            }
            QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
                background: none;
            }
        """
        # 应用样式
        self.setStyleSheet(scrollbar_style)
        # 设置滚动条策略为仅在需要时出现
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)

        self.friends_data = []

    def mousePressEvent(self, event):
        # 重写mousePressEvent处理点击事件
        index = self.indexAt(event.pos())
        if index.isValid():
            data_content = self.model.get_friends_data()[index.row()]
            self.clicked.emit(self.index, (data_content[0], data_content[1], data_content[3]))  # 发射信号，传入选中好友的索引
        super().mousePressEvent(event)

# def showMessage(window):
#     w = CustomMessageBox(window)
#     if w.exec():
#         print(w.urlLineEdit.text())
